package com.liik.game.mvc.tiled;

import com.liik.game.mvc.GameModel;
import com.liik.game.mvc.tiled.object.Entity;
import com.liik.game.mvc.tiled.object.MovableEntity;
import com.liik.game.mvc.tiled.object.Tile;
import com.liik.game.util.Vector;

public abstract class TiledGameModel extends GameModel {
	
	public static enum Environment {
		Air,
		Fire,
		Water
	}

	private Tile[][] tiles;
	private Environment[][] environment;
	
	public TiledGameModel(int width, int height, int maxMenuEntries) {
		super(maxMenuEntries);
		tiles = new Tile[width][height];
		environment = new Environment[width][height];
	}

	public final int getWidth() {
		return tiles.length;
	}

	public final int getHeight() {
		return tiles[0].length;
	}

	public final Tile getTile(int x, int y) {
		if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
			return tiles[x][y];
		}
		return null;
	}

	public final Tile getTile(float x, float y) {
		int ix = (int) Math.floor(x);
		int iy = (int) Math.floor(y);
		return getTile(ix, iy);
	}

	public final Tile[][] getTiles() {
		return tiles;
	}
	
	public final void resetEnvironment() {
		for (int i = 0; i < environment.length; ++i) {
			for (int j = 0; j < environment[0].length; ++j) {
				environment[i][j] = Environment.Air;
			}
		}
	}

	public final Environment getEnvironment(float x, float y) {
		int ix = (int) Math.floor(x);
		int iy = (int) Math.floor(y);
		return getEnvironment(ix, iy);
	}

	public final Environment getEnvironment(int x, int y) {
		if (x >= 0 && x < getWidth() && y >= 0 && y < getHeight()) {
			return environment[x][y];
		}
		return Environment.Air;
	}
	
	public final Environment[][] getEnvironment() {
		return environment;
	}

	private Vector entityFromPointHelper = new Vector();
	
	public Entity getEntityFromPoint(float x, float y) {
		Entity hero = getHero();
		entityFromPointHelper.set(x, y);
		entityFromPointHelper.sub(hero);
		if (entityFromPointHelper.length() <= hero.boundingRadius) {
			return hero;
		}		
		Entity[] entities = getAllEntities();		
		for (int i = 0; i < entities.length; ++i) {
			if (entities[i] != null) {
				entityFromPointHelper.set(x, y);
				entityFromPointHelper.sub(entities[i]);
				if (entityFromPointHelper.length() <= entities[i].boundingRadius) {
					return entities[i];
				}
			}
		}
		return null;
	}
	
	public final Vector getPointOfInterest() {
		return getHero();
	}

	public abstract MovableEntity getHero();

	public abstract Entity[] getAllEntities();
}
